package base.generic.demo11;

import java.util.List;

import org.junit.Test;

/**
 *  <T> :代表泛型，<T extends ClassA>的使用
 * 	List<String> —- 参数化的类型 
 * 	List<T> —- 泛型，在类定义时使用，如果单独用在方法上会提示E未定义为一个类。 
 * 	List<?> —- 无限制通配符类型。如果作为方法返回值，可以返回任何对象列表；
 * 	            如果作为引用变量，只能接收方法返回List<xx>，不能通过add()来添加具体对象。 
 *
 *  <T extends SomeClass> —- 有限制类型参数 
 *  List <? extends SomeClass>—- 有限制通配符类型 
 *  <T extends Comparable<T>> —– 递归类型限制 
 *  static <T> List<T> asList(T[] a) —- 泛型方法定义
 *
 *
 * 	<T extends ClassA> 与 <? extends ClassA>有什么区别
 * 	首先我们明确一下两边的名字，限制类型 & 通配符类型，
 * 	<T extends ClassA>表示后续都只能使用E进行某些判断或操作，
 * 	而<? extends ClassA> ？表示后续使用时可以是任意的。
 */
public class TestCase {

    /**
        泛型化的方法定义案例1
     */
    public <T> T maximum2(T x, T y, T z){
        return x;
    }
    /**
     泛型化的方法定义案例2
     */
    public <T> List<T> asList(T[] t){
        return null;
    }


    /**
     *  <E extends ClassA>的使用
     *	返回“最大值”，“最大值”的定义为：整型、浮点型返回最大值，字符串返回字典序最大者(类型不同，
     *	但能通过同一个方法实现比较，用T来表示不同类型)。
     *	由于想调用compareTo函数，我们让所有参数都继承Comparable,即 T extends Comparable<T>
     *
     *	<T extends Comparable<T>> 因是泛型方法，这个格式是对泛型方法的声明。
     */
    public static <T extends Comparable<T>> T maximum(T x, T y, T z){
        T max = x;

        if (y.compareTo(x)>0) {
            max = y;
        }

        if (z.compareTo(max)>0) {
            max = z;
        }
        return max;
    }


    @Test
    public void testCase1(){
        System.out.printf("Max of %d,%d and %d is %d\n", 3,5,4, maximum(3, 5, 4));
        System.out.printf("Max of %.1f, %.1f and %.1f is %.1f\n", 6.6,8.8,7.7, maximum(6.6, 8.8, 7.7));
        System.out.printf("Max of %s, %s and %s is %s\n", "pear","apple","orange", maximum("pear","apple","orange"));
    }
}
